import numpy as np
import folium
import math
import json
import time

x_pi = 3.14159265358979324 * 3000.0 / 180.0
pi = 3.1415926535897932384626  # π
a = 6378245.0  # 长半轴
ee = 0.00669342162296594323  # 扁率


def _transformlat(lng, lat):
    ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + \
          0.1 * lng * lat + 0.2 * math.sqrt(math.fabs(lng))
    ret += (20.0 * math.sin(6.0 * lng * pi) + 20.0 *
            math.sin(2.0 * lng * pi)) * 2.0 / 3.0
    ret += (20.0 * math.sin(lat * pi) + 40.0 *
            math.sin(lat / 3.0 * pi)) * 2.0 / 3.0
    ret += (160.0 * math.sin(lat / 12.0 * pi) + 320 *
            math.sin(lat * pi / 30.0)) * 2.0 / 3.0
    return ret

def _transformlng(lng, lat):
    ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + \
          0.1 * lng * lat + 0.1 * math.sqrt(math.fabs(lng))
    ret += (20.0 * math.sin(6.0 * lng * pi) + 20.0 *
            math.sin(2.0 * lng * pi)) * 2.0 / 3.0
    ret += (20.0 * math.sin(lng * pi) + 40.0 *
            math.sin(lng / 3.0 * pi)) * 2.0 / 3.0
    ret += (150.0 * math.sin(lng / 12.0 * pi) + 300.0 *
            math.sin(lng / 30.0 * pi)) * 2.0 / 3.0
    return ret

def out_of_china(lng, lat):
    return not (73.66 < lng < 135.05 and 3.86 < lat < 53.55)

def wgs84_to_gcj02(lng, lat):
    if out_of_china(lng, lat):
        return lng, lat
    dlat = _transformlat(lng - 105.0, lat - 35.0)
    dlng = _transformlng(lng - 105.0, lat - 35.0)
    radlat = lat / 180.0 * pi
    magic = math.sin(radlat)
    magic = 1 - ee * magic * magic
    sqrtmagic = math.sqrt(magic)
    dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi)
    dlng = (dlng * 180.0) / (a / sqrtmagic * math.cos(radlat) * pi)
    mglat = lat + dlat
    mglng = lng + dlng
    return [mglng, mglat]

def load_gps_data(filename):
    with open(filename, 'r', encoding='utf-8') as f:
        gps_list = json.load(f)
    return gps_list

def gps_difference_too_small(data_list, threshold=0.0001):
    base = data_list[0]
    for item in data_list[1:]:
        if abs(base["LBSLON"] - item["LBSLON"]) > threshold or abs(base["LBSLAT"] - item["LBSLAT"]) > threshold:
            return False
    return True

def PlotPointOnMap():
    # 读取数据
    gps_data = load_gps_data("gps_data.txt")

    # 判断是否所有点都差不多，如果是则只取第一个
    if gps_difference_too_small(gps_data, threshold=0.0001):
        gps_data = [gps_data[0]]

    # 使用第一个点初始化地图
    center_gcj = wgs84_to_gcj02(gps_data[0]["LBSLON"], gps_data[0]["LBSLAT"])
    san_map = folium.Map(
        location=[center_gcj[1], center_gcj[0]],
        zoom_start=16,
        # tiles='http://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
        tiles='http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}', # 高德街道图
        attr='高德地图'
    )

    # 绘制所有标记
    for i, item in enumerate(gps_data):
        gcj02_coords = wgs84_to_gcj02(item["LBSLON"], item["LBSLAT"])
        folium.Marker(
            [gcj02_coords[1], gcj02_coords[0]],
            popup=f'第{i+1}个位置',
            icon=folium.Icon(color='red')
        ).add_to(san_map)

    san_map.save('./templates/map.html')

# def main():
#     while True:
#         PlotPointOnMap()
#         time.sleep(30)

# if __name__ == '__main__':
#     main()
